import { EditorModels } from "./EditorModels";
import EditorCommand from "./commands/EditorCommands";

export interface IEditorHistoryOptions {
    editor: EditorModels
}
const EVENT_EDITOR_HISTORY_CHANGE = "EVENT_EDITOR_HISTORY_CHANGE"
export default class EditorHistory {
    editor: EditorModels;
    /** 撤销集合 */
    undos: EditorCommand[] = [];
    /** 恢复集合 */
    redos: EditorCommand[] = [];
    lastCmdTime = Date.now();
    historyDisabled = false;
    idCounter = 0
    constructor(options: IEditorHistoryOptions) {
        this.editor = options.editor
    }

    execute(cmd: EditorCommand, optionalName: string) {
        const lastCmd = this.undos[this.undos.length - 1];
        const timeDifference = Date.now() - this.lastCmdTime;

        // @ts-ignore
        const isUpdatableCmd = lastCmd && lastCmd.object === cmd.object && lastCmd.type === cmd.type && lastCmd.script === cmd.script && lastCmd.attributeName === cmd.attributeName;
        if (isUpdatableCmd && timeDifference < 500) {

            lastCmd.update(cmd);
            cmd = lastCmd;

        } else {
            this.undos.push(cmd);
            cmd.id = ++this.idCounter;
        }

        cmd.name = (optionalName !== undefined) ? optionalName : cmd.name;
        // cmd.execute();
        this.lastCmdTime = Date.now();
        this.redos = [];
    }

    // 撤销
    undo() {
        if (this.historyDisabled) {
            alert('不可以执行历史记录');
            return;
        }
        let cmd: EditorCommand | undefined;
        if (this.undos.length > 0) {
            cmd = this.undos.pop();
            // if ( cmd.inMemory === false ) {
            // 	cmd.fromJSON( cmd.json );
            // }
        }
        if (cmd !== undefined) {
            cmd.undo();
            this.redos.push(cmd);
            this.editor.$emit(EVENT_EDITOR_HISTORY_CHANGE, cmd);
        }
        return cmd;
    }
    // 恢复
    redo() {
        if (this.historyDisabled) {
            alert('不可以恢复');
            return;
        }
        let cmd = undefined;
        if (this.redos.length > 0) {
            cmd = this.redos.pop();
            // if (cmd.inMemory === false) {
            //     cmd.fromJSON(cmd.json);
            // }
        }
        if (cmd !== undefined) {
            cmd.execute();
            this.undos.push(cmd);
            this.editor.$emit(EVENT_EDITOR_HISTORY_CHANGE, cmd);
        }
        return cmd;
    }

    clear() {

        this.undos = [];
        this.redos = [];
        this.idCounter = 0;

        this.editor.$emit(EVENT_EDITOR_HISTORY_CHANGE);

    }

}
